package com.zzyl.nursing.service.impl;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.MemberThreadLocal;
import com.zzyl.framework.web.service.TokenService;
import com.zzyl.nursing.domain.Elder;
import com.zzyl.nursing.domain.FamilyMemberElder;
import com.zzyl.nursing.domain.Reservation;
import com.zzyl.nursing.dto.UserLoginRequestDto;
import com.zzyl.nursing.dto.UserRelatedElderDto;
import com.zzyl.nursing.mapper.ElderMapper;
import com.zzyl.nursing.mapper.FamilyMemberElderMapper;
import com.zzyl.nursing.mapper.ReservationMapper;
import com.zzyl.nursing.service.WechatService;
import com.zzyl.nursing.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;


import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.FamilyMemberMapper;
import com.zzyl.nursing.domain.FamilyMember;
import com.zzyl.nursing.service.IFamilyMemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * 老人家属Service业务层处理
 * 
 * @author szc
 * @date 2025-08-20
 */
@Service
@Slf4j
public class FamilyMemberServiceImpl extends ServiceImpl<FamilyMemberMapper, FamilyMember> implements IFamilyMemberService
{



    static List<String> DEFAULT_NICKNAME_PREFIX = ListUtil.of(
            "生活更美好",
            "大桔大利",
            "日富一日",
            "好柿开花",
            "柿柿如意",
            "一椰暴富",
            "大柚所为",
            "杨梅吐气",
            "天生荔枝"
    );



    @Autowired
    private FamilyMemberMapper familyMemberMapper;

    @Autowired
    private WechatService wechatService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private ReservationMapper reservationMapper;

    @Autowired
    private FamilyMemberElderMapper familyMemberElderMapper;

    @Autowired
    private ElderMapper  elderMapper;


    /**
     * 查询老人家属
     * 
     * @param id 老人家属主键
     * @return 老人家属
     */
    @Override
    public FamilyMember selectFamilyMemberById(Long id)
    {
        return familyMemberMapper.selectById(id);
    }

    /**
     * 查询老人家属列表
     * 
     * @param familyMember 老人家属
     * @return 老人家属
     */
    @Override
    public List<FamilyMember> selectFamilyMemberList(FamilyMember familyMember)
    {
        return familyMemberMapper.selectFamilyMemberList(familyMember);
    }

    /**
     * 新增老人家属
     * 
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int insertFamilyMember(FamilyMember familyMember)
    {
        return familyMemberMapper.insert(familyMember);
    }

    /**
     * 修改老人家属
     * 
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int updateFamilyMember(FamilyMember familyMember)
    {
        return familyMemberMapper.updateById(familyMember);
    }

    /**
     * 批量删除老人家属
     * 
     * @param ids 需要删除的老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberByIds(Long[] ids)
    {
        return familyMemberMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除老人家属信息
     * 
     * @param id 老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberById(Long id)
    {
        return familyMemberMapper.deleteById(id);
    }

    /**
     * 添加预约
     * @param reservationVo
     */
    @Override
    public void addReservation(ReservationVo reservationVo) {
        Reservation reservation = BeanUtil.toBean(reservationVo, Reservation.class);
        reservation.setCreateBy(MemberThreadLocal.getMemberId().toString());
        reservation.setCreateTime(DateUtils.getNowDate());
        reservation.setStatus(0);
        reservationMapper.insertReservation(reservation);
    }

    @Override
    public PageResult<Reservation> page(Integer pageNum, Integer pageSize, Integer status) {
        //分页查询
        Long id = MemberThreadLocal.getMemberId();
        LambdaQueryWrapper<Reservation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Reservation::getCreateBy, id)
                .eq(Objects.nonNull(status),Reservation::getStatus, status);
        PageHelper.startPage(pageNum, pageSize);
        Page<Reservation> page = (Page<Reservation>) reservationMapper.selectList(queryWrapper);
        return new PageResult<>(page.getTotal(), page.getResult());
    }

    /**
     * 添加家属和老人关系
     * @param userRelatedElderDto
     */
    @Override
    public void addUserRelatedElder(UserRelatedElderDto userRelatedElderDto) {
        String idCard = userRelatedElderDto.getIdCard();
        String name = userRelatedElderDto.getName();
        LambdaQueryWrapper<Elder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Elder::getIdCardNo, idCard)
                .eq(Elder::getName, name);
        Elder elder = elderMapper.selectOne(queryWrapper);
        if (Objects.isNull(elder)) {
            throw new BaseException("填写的身份证号或者名字错误");
        }else if (elder.getStatus() == 0||elder.getStatus() == 5){
            throw new BaseException("该老人并未入住养老院");
        }else {
            //该家属是否已绑定过该老人
            if (familyMemberElderMapper.exists(new LambdaQueryWrapper<FamilyMemberElder>().eq(
                    FamilyMemberElder::getElderId, elder.getId())
                    .eq(FamilyMemberElder::getFamilyMemberId, MemberThreadLocal.getMemberId())
            )) {
                throw new BaseException("您已绑定过该老人");
            }
            FamilyMemberElder familyMemberElder = new FamilyMemberElder();
            familyMemberElder.setFamilyMemberId(MemberThreadLocal.getMemberId());
            familyMemberElder.setElderId(elder.getId());
            familyMemberElder.setRemark(userRelatedElderDto.getRemark());
            familyMemberElderMapper.insert(familyMemberElder);
        }
    }

    @Override
    public List<FamilyMemberElderVo> getAllRelatedElders() {
        return familyMemberElderMapper.getAllRelatedElders(MemberThreadLocal.getMemberId());
    }

    @Override
    public List<PageQueryRelatedElderVo> listByPage(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        Page<PageQueryRelatedElderVo> page = (Page) familyMemberElderMapper.listByPage(MemberThreadLocal.getMemberId());
        return page.getResult();
    }


    /**
     * 解除绑定
     * @param id
     */
    @Override
    public void deleteRelation(Long id) {
        familyMemberElderMapper.deleteById(id);
    }

    @Override
//    @Scheduled(cron = "0 1,31 * * * ?")
    public void updateReservationStatus() {
        LocalDateTime now = LocalDateTime.now();
        LambdaQueryWrapper<Reservation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Reservation::getStatus, 0);
        List<Reservation> reservations = reservationMapper.selectList(queryWrapper);
        reservations.forEach(reservation -> {
            if (reservation.getTime().isBefore(now)) {
                reservation.setStatus(3);
                reservationMapper.updateReservation(reservation);
            }
        });
    }

    /**
     * 每个时间段剩余预约次数
     * @return
     */
    @Override
    public List<ReservationCountVo> countByTime(Long time) {
        //毫秒转化为LocalDate
        LocalDateTime startTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault());
        LocalDateTime endTime=startTime.plusDays(1);
        return reservationMapper.countByTime(startTime,endTime);
    }

    /**
     * 取消预约
     * @param id
     */
    @Override
    public void cancel(Long id) {
        Reservation reservation = new Reservation();
        reservation.setId(id);
        reservation.setUpdateBy(MemberThreadLocal.getMemberId().toString());
        reservation.setUpdateTime(DateUtils.getNowDate());
        reservation.setStatus(2);
        reservationMapper.updateReservation(reservation);
    }


    /**
     * 获取取消的参观预约数量
     * @return
     */
    @Override
    public Long getCancelledCount() {
        //获取今天开始和结束
        Long time = System.currentTimeMillis();
        LocalDateTime ldt = LocalDateTimeUtil.of(time);
        LocalDateTime startTime = ldt.toLocalDate().atStartOfDay();
        LocalDateTime endTime = startTime.plusDays(1);
        //获取用户id
        Long id = MemberThreadLocal.getMemberId();
        LambdaQueryWrapper<Reservation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Reservation::getUpdateBy, id)
                .eq(Reservation::getStatus, 2)
                .ge(Reservation::getUpdateTime, startTime)
                .le(Reservation::getUpdateTime, endTime);
        Long count = reservationMapper.selectCount(queryWrapper);
        if (count>3){
            throw new BaseException("取消预约的数量超过3次，请明天再预约");
        }
        return count;
    }

    @Override
    public LoginVo login(UserLoginRequestDto userLoginRequestDto) {
        // 1.调用小程序接口openId
        String openid = wechatService.getOpenid(userLoginRequestDto.getCode());
        // 2.根据openIda查询用户
        LambdaQueryWrapper<FamilyMember> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FamilyMember::getOpenId, openid);
        FamilyMember familyMember = familyMemberMapper.selectOne(queryWrapper);

        // 3.如果用户为空，则创建对象，openId设置到对象中
        if (Objects.isNull(familyMember)){
            familyMember=FamilyMember.builder().openId(openid).build();
        }
        // 4.调用微信api获取手机号
        familyMember.setPhone(wechatService.getPhone(userLoginRequestDto.getPhoneCode()));

        // 5.保存或者修改用户
        saveOrUpdateFamilyMember(familyMember);

        // 6.将用户Id,name存入token
        LoginVo loginVo = new LoginVo();
        log.warn("familyMember: {}", familyMember);
        Map<String, Object> claims = Map.of("id", familyMember.getId(), "nickName", familyMember.getName());
        String token = tokenService.createToken(claims);
        loginVo.setNickName(familyMember.getName());
        loginVo.setToken(token);
        return loginVo;
    }

    private void saveOrUpdateFamilyMember(FamilyMember familyMember) {
        // 如果是新用户，设置默认昵称
        if (familyMember.getId() == null) {
            String phone = familyMember.getPhone();
            String nickName = DEFAULT_NICKNAME_PREFIX.get(RandomUtil.randomInt(DEFAULT_NICKNAME_PREFIX.size()))
                    + (phone != null && phone.length() >= 4 ? phone.substring(phone.length() - 4) : "");
            familyMember.setName(nickName);
        }
        // 使用MP的saveOrUpdate方法
        this.saveOrUpdate(familyMember);
    }
}
